package com.mxpio.erp.equipment.controller;

import com.mxpio.erp.common.equipment.entity.EquipmentPersonGroup;
import com.mxpio.erp.common.equipment.entity.EquipmentPersonGroupDetail;
import com.mxpio.erp.common.equipment.service.EquipmentPersonGroupService;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.policy.CrudContext;
import com.mxpioframework.jpa.policy.impl.SmartCrudPolicyAdapter;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.jpa.query.SimpleCriterion;
import com.mxpioframework.security.entity.Dept;
import com.mxpioframework.security.service.DeptService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.HashSet;
import java.util.List;


@Tag(name = "EquipmentPersonGroupController}", description = "人员群组管理")
@RestController
@RequestMapping("/erp/equipment/group/")
public class EquipmentPersonGroupController {

    @Autowired
    private EquipmentPersonGroupService equipmentPersonGroupService;
    @Autowired
    private DeptService deptService;


    @GetMapping("list")
    @Operation(summary = "人员群组管理列表", description = "获取人员群组管理列表（无分页）", method = "GET")
    public Result<List<EquipmentPersonGroup>> list(@Parameter(description = "查询参数") Criteria criteria) throws UnsupportedEncodingException {
        List<EquipmentPersonGroup> list = equipmentPersonGroupService.list(EquipmentPersonGroup.class, criteria);
        return Result.OK(list);
    }

    @GetMapping("page")
    @Operation(summary = "人员群组管理列表", description = "获取人员群组管理列表（分页）", method = "GET")
    public Result<Page<EquipmentPersonGroup>> page(@Parameter(description = "查询参数") Criteria criteria, @Parameter(description = "每页条数") Integer pageSize, @Parameter(description = "页号") Integer pageNo) throws UnsupportedEncodingException {
        Pageable page = PageRequest.of(pageNo - 1, pageSize);
        Criteria c = Criteria.create();
        List<Object> criterions = criteria.getCriterions();
        for (Object obj : criterions){
            if(obj instanceof SimpleCriterion){
                SimpleCriterion simpleCriterion = (SimpleCriterion) obj;
                if("orgCode".equals(simpleCriterion.getFieldName())){
                    List<Dept> deptTree = deptService.getDeptTree(Criteria.create());
                    Object value = simpleCriterion.getValue();
                    if(value != null){
                        HashSet<String> set = new HashSet<>();
                        String orgCode = (String) value;
                        set.add(orgCode);
                        getTreeDeptCode(orgCode, set,deptTree);
                        c.addCriterion("orgCode", Operator.IN, set);
                    }

                }else{
                    c.addCriterion(obj);
                }
            }else {
                c.addCriterion(obj);
            }
        }

        Page<EquipmentPersonGroup> pageResult = equipmentPersonGroupService.listPage(EquipmentPersonGroup.class, page, c);
        return Result.OK(pageResult);
    }

    private void getTreeDeptCode(String deptCode, HashSet<String> codeSet,List<Dept> children){
        for (Dept dept :children){
            if (StringUtils.isNotEmpty(deptCode)){
                if (deptCode.equals(dept.getDeptCode())) {
                    codeSet.add(dept.getDeptCode());
                    getTreeDeptCode("",codeSet, dept.getChildren());
                }else{
                    getTreeDeptCode(deptCode,codeSet, dept.getChildren());
                    continue;
                }
            }
            codeSet.add(dept.getDeptCode());
            getTreeDeptCode("",codeSet, dept.getChildren());
        }

    }


    @GetMapping("list/{id}")
    @Operation(summary = "根据ID获取人员群组管理列表", description = "根据ID获取人员群组管理列表", method = "GET")
    public Result<EquipmentPersonGroup> getById(@PathVariable(name = "id", required = true) String id) {
        EquipmentPersonGroup equipmentPersonGroup = equipmentPersonGroupService.getById(EquipmentPersonGroup.class, id);
        return Result.OK(equipmentPersonGroup);
    }

    @GetMapping("listByGroupCode/{groupCode}")
    @Operation(summary = "根据群组编码获取人员群组管理列表", description = "根据群组编码获取人员群组管理列表", method = "GET")
    public Result<List<EquipmentPersonGroup>> getByGroupCode(@PathVariable(name = "groupCode", required = true) String groupCode) {
        Criteria criteria = Criteria.create();
        criteria.addCriterion("groupCode", Operator.EQ, groupCode);
        List<EquipmentPersonGroup> list = equipmentPersonGroupService.list(EquipmentPersonGroup.class, criteria);
        return Result.OK(list);
    }

    @RequestMapping("add")
    @Operation(summary = "保存人员群组管理", description = "保存人员群组管理")
    public Result<EquipmentPersonGroup> add(@RequestBody EquipmentPersonGroup equipmentPersonGroup) {
        equipmentPersonGroupService.save(equipmentPersonGroup, new SmartCrudPolicyAdapter() {
            @Override
            public boolean beforeInsert(CrudContext context) {
                Object o = context.getEntity();
                if (o instanceof EquipmentPersonGroupDetail) {
                    EquipmentPersonGroup parent = context.getParent();
                    ((EquipmentPersonGroupDetail) o).setGroupId(parent.getId());
                }
                return true;
            }
        });
        return Result.OK(equipmentPersonGroup);
    }

    @PutMapping("edit")
    @Operation(summary = "编辑人员群组管理", description = "编辑人员群组管理", method = "PUT")
    public Result<EquipmentPersonGroup> edit(@RequestBody EquipmentPersonGroup equipmentPersonGroup) {
        equipmentPersonGroupService.update(equipmentPersonGroup);
        return Result.OK(equipmentPersonGroup);
    }

    @DeleteMapping("remove/{ids}")
    @Operation(summary = "根据id删除人员群组管理", description = "删除人员群组管理,多个id用英文逗号分隔", method = "DELETE")
    public Result<EquipmentPersonGroup> remove(@PathVariable(name = "ids", required = true) String ids) {
        String[] id = ids.split(",");
        for (String key : id) {
            equipmentPersonGroupService.delete(EquipmentPersonGroup.class, key, new SmartCrudPolicyAdapter() {
                @Override
                public boolean beforeDelete(CrudContext context) {
                    Object o = context.getEntity();
                    if (o instanceof EquipmentPersonGroup) {
                        try {
                            JpaUtil.lind(EquipmentPersonGroupDetail.class).equal("groupId", ((EquipmentPersonGroup) o).getId()).delete();
                        } catch (Exception e) {
                            return false;
                        }
                    }
                    return true;
                }
            });
        }
        return Result.OK();
    }

    @GetMapping("get_by_user/{userId}")
    @Operation(summary = "根据用户获取所属的组", description = "根据用户获取所属的组", method = "GET")
    public Result<List<EquipmentPersonGroup>> list(@Parameter(description = "用户username")@PathVariable(name = "userId", required = true) String userId,
                                                   @Parameter(description = "用户组过滤条件") Criteria criteria){
        return equipmentPersonGroupService.getGroupListByUserId(userId, criteria);
    }

}
